package com.m4f.city.web.controller.api;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.http.json.JsonHttpParser;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonParser;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.Key;
import com.m4f.city.business.domain.InternalUser;
import com.m4f.city.utils.serializer.M4FJsonSerializer;
import com.m4f.city.utils.serializer.M4FXmlSerializer;
import com.m4f.city.utils.serializer.TestModelSerializable;

@Controller
@RequestMapping("/api/user")
public class UserApiController extends ApiBaseController {
		
	@RequestMapping("/info")
	@ResponseBody
	public Map<String, Object> getUserInfo(Principal principal, HttpServletResponse response) throws Exception {
		HashMap<String, Object> map = new HashMap<String, Object>();
		InternalUser user = null;
		
		if(principal instanceof OAuth2Authentication) {
			OAuth2Authentication auth = (OAuth2Authentication) principal;
			user = (InternalUser) auth.getUserAuthentication().getPrincipal();
		} else {
			throw new Exception("You are not using oauth!"); // TODO create a m4f exception!!!!
		}
		
		StringBuilder sb = new StringBuilder();
		try {
			//PrintWriter out = response.getWriter();
			//response.setContentType("application/json");
			// TESTING
			ArrayList<Integer> tests = new ArrayList<Integer>();
			tests.add(1);
			tests.add(2);
			tests.add(3);
			//user.setTests(tests);
			// END TESTING
			M4FJsonSerializer serializer = new M4FJsonSerializer(); // TODO injection!
			
			map = serializer.getMap(user);
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		return map;
	}
	
	
	public void getUserInfo_old(Principal principal, HttpServletResponse response) {
		/*try {
			ApiService apiService = this.serviceLocator.getApiService();
			return apiService.getUserInfo();
		} catch(Exception e) {
			e.printStackTrace();
		}*/
		
		
		
		InternalUser user = null;
		if(principal instanceof OAuth2Authentication) {
			OAuth2Authentication auth = (OAuth2Authentication) principal;
			user = (InternalUser) auth.getUserAuthentication().getPrincipal();
		} else {
			user = new InternalUser();
			user.setId(Long.valueOf(9999));
			user.setEmail("mimail@m4f.es");
			user.setName("Mi name");
		}
		
		StringBuilder sb = new StringBuilder();
		try {
			PrintWriter out = response.getWriter();
			response.setContentType("application/json");
			
			// START CUSTOM SERIAL TEST
			M4FXmlSerializer serializer = new M4FXmlSerializer(); // TODO use the factory!!!
			byte[] bytes = serializer.serialize(new TestModelSerializable());
			
			TestModelSerializable test = serializer.deserialize(TestModelSerializable.class, bytes);
			String xml = new String(bytes);
			// END CUSTOM SERIAL TEST
			
			
			/*XStream xstream = new XStream();
			String xml = xstream.toXML(user);*/
			//out.write(xml);
			
			// START CUSTOM JSON SERIAL TEST
			M4FJsonSerializer jSerial = new M4FJsonSerializer();
			String jsonSerial = new String(jSerial.serialize(new TestModelSerializable()));
			// END CUSTOM JSON SERIAL TEST
			
			out.write(jsonSerial);
			
			JsonFactory jsonFactory = new JacksonFactory();
			JsonParser parser = jsonFactory.createJsonParser(jsonSerial);
			parser.nextToken();
			
			InternalUser usuario = parser.parseAndClose(InternalUser.class, null);
			int a = 0;
			
			
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	@RequestMapping("/test")
	public void test(Principal principal, HttpServletResponse response) {
		 // setup up the HTTP transport
        HttpTransport transport = new NetHttpTransport();
        // add default headers
        GoogleHeaders headers = new GoogleHeaders();
        headers.setApplicationName("Hirubila/1.0");
        transport.defaultHeaders = headers;
  
        //JsonCParser parser = new JsonCParser();
        JsonHttpParser parser = new JsonHttpParser();
        parser.jsonFactory = new JacksonFactory();
        transport.addParser(parser);

        // build the HTTP POST request and URL
        HttpRequest request = transport.buildPostRequest();
        request.setUrl("http://192.168.1.14:8080/es/api/user/info");
    
        HttpResponse responseNew;
		try {
			responseNew = request.execute();
			//LOGGER.severe(response.parseAsString());  
			
			// MORE TEST
			StringBuffer sb = new StringBuffer();
			byte[] bytes = new byte[1024];
			int length = 0;
			int totalLength = 0;
			while((length = responseNew.getContent().read(bytes)) > 0) {
				totalLength += length;
				sb.append(new String(bytes));
			}
			String s = sb.toString().substring(0, totalLength);
			M4FJsonSerializer serializer = new M4FJsonSerializer();
			InternalUser testUser = serializer.deserialize(InternalUser.class, s.getBytes());
			// END MORE TEST
			
	       // TestModelSerializable result = responseNew.parseAs(TestModelSerializable.class);
	        int a = 0;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
       
        /*HttpResponse responseNew;
		try {
			responseNew = request.execute();
			//LOGGER.severe(response.parseAsString());  
	        User result = responseNew.parseAs(User.class);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
	}
	
	@ResponseBody
	@RequestMapping("/testMap")
	public HashMap<String, Object> testMap() {
		M4FJsonSerializer serializer = new M4FJsonSerializer(); // TODO use the factory!!!
		TestModelSerializable test = new TestModelSerializable();
		
		return serializer.getMap(test);
	}
	
	public static class User extends GenericJson {        
        @Key("id")
        public String id;
        
    }
}
